home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 016a / 4dtnt.zip / BUMP.DOC < prev    next >
Text File  |  1991-11-03  |  5KB  |  187 lines

  1.     A major idea here is the use of the VALUE of an environment variable
  2.     whose NAME is passed by the caller.  The result is something like a
  3.     function in a high level programming language.
  4.  
  5.  
  6.     if either argument is omitted or the variable is not in the environment
  7.      ("%[%2]" == ""), put up the help text and quit with an errorlevel.
  8.     
  9. if "%1" == "" .or. "%2" == "" .or. "%[%2]" == "" goto help
  10.  
  11.     Make all letters upper case to get away from case sensitivity.
  12. set $foo=%@upper[%1]
  13.  
  14.     Make a string of all the digits from 0 to 35.
  15. set $wstr=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
  16.  
  17.     Use the semantic equivalent of a "case" statement to check what
  18.     number base the user wants (specified in %1).  The numbers 2 to 36
  19.     are allowed, along with certain mnemonic letters, such as "H" for
  20.     hexadecimal.  "A"lpha is a special case where only the letters of
  21.     the alphabet are used -- not numeric digit characters.
  22.  
  23. iff      %$foo = A then ^ gosub alpha
  24.  elseiff %$foo = B then ^ gosub binary
  25.  elseiff %$foo = O then ^ gosub octal
  26.  elseiff %$foo = H then ^ gosub hex
  27.  elseiff %$foo = D then ^ gosub dec
  28.  elseiff %$foo = N then ^ gosub an
  29.  elseiff %$foo gt 1 .and. %$foo lt 37 then ^ gosub base
  30.  else goto help
  31. endiff
  32.  
  33. iff %$val ne 0 then^unset %2 ^ gosub cleanup ^ goto helpval
  34.  else set %2=%$foo ^gosub cleanup^quit 0
  35. endiff
  36.  
  37.    We actually finish here.  Everything else is subroutines.
  38. quit
  39.  
  40. :cleanup
  41.    Can't use SETLOCAL because we're modifying the immediate caller's 
  42.    environment on purpose.  Therefore, we have to UNSET our own stuff.
  43. unset $foo $wstr $val $max >& nul
  44. return
  45.  
  46.    Each of the following little subroutines just sets a key parameter
  47.    for the main "bumpit" subroutine.
  48.  
  49. :alpha
  50. set $max=25
  51. set $wstr=%@substr[%$wstr,10,26]
  52. gosub bumpit
  53. return
  54.  
  55. :binary
  56. set $max=1
  57. gosub bumpit
  58. return
  59.  
  60. :octal
  61. set $max=7
  62. gosub bumpit
  63. return
  64.  
  65. :hex
  66. set $max=15
  67. gosub bumpit
  68. return
  69.  
  70. :dec
  71. set $max=9
  72. gosub bumpit
  73. return
  74.  
  75. :an
  76. set $max=35
  77. gosub bumpit
  78. return
  79.  
  80. :base
  81. set $max=%@eval[%$foo-1]
  82. gosub bumpit
  83. return
  84.  
  85.    Here's the beef!  All of the above just set the parameters for this.
  86.  
  87. :bumpit
  88.  
  89.    Make sure all the characters in the input string are valid for this
  90.    number base so the result will be meaningful.
  91.  
  92. gosub validate
  93. if %$val ne 0 return
  94.  
  95.    Aw, shucks, it's valid.  Get to work.
  96.  
  97.    Standardize character case
  98. set $foo=%@upper[%[%2]]
  99.  
  100.    Limit the loop to the length of the variable for carry propagation
  101. set $i=%@len[%$foo]
  102. set $j=%@eval[%$i-1]
  103. set $k=%$j
  104.  
  105. :bumploop
  106.     
  107.     Break the string into three parts: front, target, and rear.  "Target"
  108.     is the character to be incremented (usually the rightmost unless we
  109.     are propagating a carry leftward).  "Front" is the part of the string
  110.     up to but not including "target".  "Rear" is the part of the string
  111.     which follows "target".  Either "front" or "rear" may be empty.  "Rear"
  112.     is usually empty unless propagating a carry.  If "front" is empty, there
  113.     is no place to propagate a carry, even if it is necessary.  The latter
  114.     could be changed easily if desired.
  115.  
  116. set $front=
  117. if %$j gt 0 set $front=%@substr[%$foo,0,%$j]
  118. set $targ=%@substr[%$foo,%$j,1]
  119. set $rear=
  120. if %$j lt %$k set $rear=%@substr[%$foo,%@eval[%$j+1],%@eval[%$k-%$j]]
  121.  
  122.     Check to see if "targ" is already at the limit for the number system.
  123.     Zero it and keep going if necessary.
  124.  
  125. set $l=%@index[%$wstr,%$targ]
  126. iff %$l lt %$max then ^ set $targ=%@substr[%$wstr,%@eval[%$l+1],1]^set $j=0
  127.   else set $targ=%@substr[%$wstr,0,1]
  128. endiff
  129.  
  130.     Put the string back together
  131.  
  132. set $foo=%[$front]%[$targ]%[$rear]
  133.  
  134.     See if another iteration one character to the left is needed.
  135.  
  136. if %$j gt 0 (set $j=%@eval[%$j-1]^goto bumploop)
  137. rem unset $i $j $k $l $front $rear $targ >& nul
  138. return
  139.  
  140.  
  141.  
  142.  
  143.    Check whether all the characters in the environment variable are
  144.    OK in this number base.  Return 0 if OK, base of the number system
  145.    if not.
  146.  
  147. :validate
  148. set $i=0
  149. :valloop
  150.    
  151.    A valid character will have an index in the "wstr" digit string less
  152.    than the base of the number system in question ("max") and greater
  153.    than -1 (i.e., not a character completely outside the "wstr" set).
  154.  
  155. set $val=%@index[%$wstr,%@substr[%[%2],%$i,1]]
  156. if %$val lt 0 .or. %$val gt %$max (set $val=%$max^return)
  157.  
  158.    Keep looping through all the characters in the input string.
  159. set $i=%@eval[%$i+1]
  160.  
  161.    Check for end of loop
  162. iff %$i lt %@len[%[%2]] then ^ goto valloop
  163.   else set $val=0^return
  164. endiff
  165. return
  166.  
  167. :helpval
  168. echo Invalid character detected.
  169. echo .
  170. goto help
  171.  
  172. :help
  173. echo Usage BUMP  mode   var
  174. echo                    
  175. echo              !      !
  176. echo              !      Any environment variable of the correct type
  177. echo              A=alpha     [A-Z]
  178. echo              B=binary    [0-1]
  179. echo              D=decimal   [0-9]
  180. echo              H=hex       [0-F]
  181. echo              N=alph/num  [0-9,A-F]
  182. echo              O=octal     [0-7]
  183. echo              [2-36]      [0-(n-1)]
  184. echo New value returned in var
  185. echo Carry propagates left, overflow is ignored
  186. quit 4
  187.